package data.framework.dao.mybatis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;

import data.framework.dao.Page;


/**
 * 数据持久层基类.
 * 此基类的使用方法必须定义自己模块的Dao类继承此抽象类，方可使用。
 * @version 1.00 2010/11/15 lujw create
 * @see org.mybatis.spring.support.SqlSessionDaoSupport
 * @see com.sailing.framework.mybatis.BaseDaoSupport
 */
@Repository
public class BaseMyBatisDao<E> extends SqlSessionDaoSupport {

	/**
	 * 实体对象类定义
	 */
	protected Class<E> entityClass;
	
	/**
	 * 设置实体对象类定义
	 */
	public void setEntityClass(Class<E> entityClass) {
		this.entityClass = entityClass;
	}

	/**
	 * 根据ID查询对象.
	 * @param primaryKey	主键
	 * @return	实体对象
	 */
	public Object getById(String primaryKey) {
		Object object = getSqlSession().selectOne(
				getFindByPrimaryKeyQuery(), primaryKey);
		return object;
	}

	/**
	 * 根据ID删除对象.
	 * @param id	主键
	 */
	public void deleteById(String id) {
		getSqlSession().delete(getDeleteQuery(), id);
	}

	/**
	 * 保存对象.
	 * @param entity	实体对象
	 * @return	影响行数
	 */
	public int save(E entity) {
		prepareObjectForSaveOrUpdate(entity);
		int rows = getSqlSession().insert(getInsertQuery(), entity);
		return rows;
	}

	/**
	 * 更新对象.
	 * @param entity	实体对象
	 * @return	影响行数
	 */
	public int update(E entity) {
		prepareObjectForSaveOrUpdate(entity);
		int rows = getSqlSession().update(getUpdateQuery(), entity);
		return rows;
	}

	/**
	 * 用于子类覆盖,在insert,update之前调用
	 * 
	 * @param o
	 */
	protected void prepareObjectForSaveOrUpdate(E entity) {
	}

	/**
	 * 生成getById查询的完整查询statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getFindByPrimaryKeyQuery() {
		return entityClass.getSimpleName() + ".getById";
	}

	/**
	 * 生成insert的完整statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getInsertQuery() {
		return entityClass.getSimpleName() + ".insert";
	}

	/**
	 * 生成update的完整statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getUpdateQuery() {
		return entityClass.getSimpleName() + ".update";
	}

	/**
	 * 生成delete的完整statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getDeleteQuery() {
		return entityClass.getSimpleName() + ".delete";
	}

	/**
	 * 生成统计（个数）的完整statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getCountQuery() {
		return entityClass.getSimpleName() + ".count";
	}
	
	/**
	 * 生成findAll的完整statementName.
	 * @return	生成的完整statementName字符串
	 */
	public String getFindAllQuery() {
		return entityClass.getSimpleName() + ".findAll";
	}

	/**
	 * 分页查询.
	 * @param statementName	查询语句ID
	 * @param page	分页信息对象
	 * @return	分页结果对象
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected Page pageQuery(String statementName, Page page) {

		Number totalCount = (Number) getSqlSession().selectOne(
getCountQuery(), page.getMapFilters());
		page.setTotalCount(totalCount.intValue());

		// 其它分页参数,用于不喜欢或是因为兼容性而不使用方言(Dialect)的分页用户使用.
		// 与getSqlMapClientTemplate().queryForList(statementName,
		// parameterObject)配合使用
		Map filters = new HashMap();
		filters.put("offset", page.getFirstResult());
		filters.put("pageSize", page.getPageSize());
		filters.put("lastRows", page.getFirstResult() + page.getPageSize());
		filters.put("sortColumns", page.getOrderString());

		// 混合两个filters为一个filters,MapAndObject.get()方法将在两个对象取值,Map如果取值为null,则再在Bean中取值

		filters.putAll((Map) page.getMapFilters());

		List list = selectList(statementName, filters, page.getFirstResult(),
				page.getPageSize());
		page.setResult(list);
		return page;
	}

	/**
	 * 集合查询（供分页查询使用）.
	 * @param statement	命名空间
	 * @param parameter	查询语句ID
	 * @param offset
	 * @param limit
	 * @return	结果集
	 */
	@SuppressWarnings("rawtypes")
	private List selectList(final String statement, final Object parameter,
			final int offset, final int limit) {
		return (List) getSqlSession().selectList(statement, parameter,
				new RowBounds(offset, limit));
	}

	/**
	 * 查询全部.
	 * @return	结果集
	 */
	@SuppressWarnings("rawtypes")
	public List findAll() {
		return getSqlSession().selectList(getFindAllQuery());
//		throw new UnsupportedOperationException();
	}
	
	/**
	 * 根据查询语句查询.
	 * @param statement	查询语句ID
	 * @param parameter	查询参数
	 * @return	结果集
	 */
	@SuppressWarnings("rawtypes")
	public List find(String statement, Object parameter) {
		return getSqlSession().selectList(statement,parameter);
	}

	/**
	 * 检测实体对象是否唯一（暂未实现）.
	 * @param entity
	 * @param entityuniquePropertyNames
	 * @return	
	 */
	@Deprecated
	public boolean isUnique(E entity, String uniquePropertyNames) {
		throw new UnsupportedOperationException();
	}

	/**
	 * 刷新缓存（暂未实现）.
	 */
	@Deprecated
	public void flush() {
		throw new UnsupportedOperationException();
	}

}
